package com.yanqu.client;

import com.yanqu.client.db.DbMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameProtocol;

import java.lang.reflect.Field;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.*;

public class ProtocolAllot {
    static String sqlUrl = "jdbc:mysql://10.1.110.200:3306/db_number_allot?useUnicode=true&characterEncoding=utf8&useSSL=false|root|Yanqufuwuduan123^%|20";
    static String selectGameSql = "select * from t_game_protocol_allot";
    static String insertGameSql = "insert into t_game_protocol_allot (protocolId,protocolName,updateTime,author,branchName) values (?,?,?,?,?)";
    static String updateGameSql = "update t_game_protocol_allot set protocolName=?,updateTime=? where protocolId=?";
    static String delGameSql = "Delete from t_game_protocol_allot where protocolId=?";

    static String selectCrossSql = "select * from t_cross_protocol_allot";
    static String insertCrossSql = "insert into t_cross_protocol_allot (protocolId,protocolName,updateTime,author,branchName) values (?,?,?,?,?)";
    static String updateCrossSql = "update t_cross_protocol_allot set protocolName=?,updateTime=? where protocolId=?";
    static String delCrossSql = "Delete from t_cross_protocol_allot where protocolId=?";

    public static List<Integer> allot(int type, String author, String branchName, int numCount, int startProtocol) {
        String selectSql = "";
        String insertSql = "";
        String updateSql = "";
        String delSql = "";
        if (type == 1) {
            selectSql = selectGameSql;
            insertSql = insertGameSql;
            updateSql = updateGameSql;
            delSql = delGameSql;
        } else {
            selectSql = selectCrossSql;
            insertSql = insertCrossSql;
            updateSql = updateCrossSql;
            delSql = delCrossSql;
            if (startProtocol < 40000) {
                startProtocol = 40000;
            }
        }


        Map<Integer, String> protocolNameMap = new HashMap<>();
        Map<Integer, String> repeatCheck = new HashMap<>();

        Connection conn = DbMgr.parseDbConfig(sqlUrl);
        if (null == conn) {
            System.out.println("链接数据库失败！！");
            return null;
        }

        try {
            conn.setAutoCommit(true);
        } catch (Exception err) {

        }

        try {
            CallableStatement call = conn.prepareCall(selectSql);
            ResultSet rs = call.executeQuery();
            while (rs.next()) {
                int protocolId = rs.getInt("protocolId");
                String protocolName = rs.getString("protocolName");
                //System.out.println(protocolName + " = " + protocolId);
                protocolNameMap.put(protocolId, protocolName);
            }
        } catch (Exception err) {

        }

        try {
            List<Field> fieldList = new ArrayList<>();

            if (type == 1) {
                fieldList.addAll(Arrays.asList(GameProtocol.class.getDeclaredFields()));
            } else {
                fieldList.addAll(Arrays.asList(CrossProtocol.class.getDeclaredFields()));
            }
            for (Field field : fieldList) {
                String protocolName = field.getName();
                int protocolId = field.getInt(null);
                if (!repeatCheck.containsKey(protocolId)) {
                    repeatCheck.put(protocolId, protocolName);
                } else {
                    System.out.println("协议有重复！！！:" + protocolName + " = " + protocolId);
                }
                if (!protocolNameMap.containsKey(protocolId)) {
                    protocolNameMap.put(protocolId, protocolName);
                    int i = 1;
                    PreparedStatement pstmt = conn.prepareStatement(insertSql);
                    pstmt.setInt(i++, protocolId);
                    pstmt.setString(i++, protocolName);
                    pstmt.setLong(i++, System.currentTimeMillis());
                    pstmt.setString(i++, author);
                    pstmt.setString(i++, branchName);
                    if (pstmt.executeUpdate() <= 0) {
                        System.out.println("插入失败:" + protocolName + " = " + protocolId);
                    }
                    pstmt.clearParameters();
                    pstmt.close();
                } else if (!Objects.equals(protocolName, protocolNameMap.get(protocolId))) {
                    protocolNameMap.put(protocolId, protocolName);
                    int i = 1;
                    PreparedStatement pstmt = conn.prepareStatement(updateSql);
                    pstmt.setString(i++, protocolName);
                    pstmt.setLong(i++, System.currentTimeMillis());
                    pstmt.setInt(i++, protocolId);
                    if (pstmt.executeUpdate() <= 0) {
                        System.out.println("更新失败:" + protocolName + " = " + protocolId);
                    }
                    pstmt.clearParameters();
                    pstmt.close();
                }
            }

            if (type == 1) {//GameProto的插入要额外判断ClientProto
                for (Field declaredField : ClientProtocol.class.getDeclaredFields()) {
                    int protocolId = declaredField.getInt(null);
                    String protocolName = declaredField.getName();
                    protocolId+=20000;
                    if (!protocolNameMap.containsKey(protocolId)) {
                        protocolNameMap.put(protocolId, protocolName);
                        int i = 1;
                        PreparedStatement pstmt = conn.prepareStatement(insertSql);
                        pstmt.setInt(i++, protocolId);
                        pstmt.setString(i++, protocolName);
                        pstmt.setLong(i++, System.currentTimeMillis());
                        pstmt.setString(i++, author);
                        pstmt.setString(i++, branchName);
                        if (pstmt.executeUpdate() <= 0) {
                            System.out.println("插入失败:" + protocolName + " = " + protocolId);
                        }
                        pstmt.clearParameters();
                        pstmt.close();
                    }
                }
            }

        } catch (Exception err) {

        }

        if (numCount <= 0) {
            System.out.println("没有指定分配数量");
            return null;
        }

        List<Integer> protocolList = new ArrayList<>(protocolNameMap.keySet());
        protocolList.sort(((o1, o2) -> {
            return o1.compareTo(o2);
        }));

        int allotStartId = 0;
        for (int i = 0; i + 1 < protocolList.size(); i++) {
            int nowId = protocolList.get(i);
            if (protocolList.get(i) < startProtocol) {
                continue;
            }
            int nextId = protocolList.get(i + 1);
            if (nextId - nowId > numCount) {
                allotStartId = nowId + 1;
                break;
            }
        }
        boolean isSuccess = true;
        try {
            for (int protocolId = allotStartId; protocolId < allotStartId + numCount; protocolId++) {
                int i = 1;
                PreparedStatement pstmt = conn.prepareStatement(insertSql);
                pstmt.setInt(i++, protocolId);
                pstmt.setString(i++, "wait_define_name");
                pstmt.setLong(i++, System.currentTimeMillis());
                pstmt.setString(i++, author);
                pstmt.setString(i++, branchName);
                if (pstmt.executeUpdate() <= 0) {
                    isSuccess = false;
                    System.out.println("分配的协议入库失败！protocolId=" + protocolId);
                    break;
                }
                pstmt.clearParameters();
                pstmt.close();
            }


        } catch (Exception err) {
            isSuccess = false;
            System.out.println(err);
        }
        List<Integer> allotProtocol = new ArrayList<>();
        try {
            if (isSuccess) {
                System.out.println("分配了协议号段: " + allotStartId + "-" + (allotStartId + numCount - 1));
            }

            for (int protocolId = allotStartId; protocolId <= allotStartId + numCount; protocolId++) {
                if (!isSuccess) {
                    int i = 1;
                    PreparedStatement pstmt = conn.prepareStatement(delSql);
                    pstmt.setInt(i++, protocolId);
                    pstmt.executeUpdate();
                    pstmt.clearParameters();
                    pstmt.close();
                } else {
                    System.out.println("分配了协议号: " + protocolId);
                    allotProtocol.add(protocolId);
                }
            }
        } catch (Exception err) {

        }


        try {
            conn.close();
        } catch (Exception err) {

        }

        return allotProtocol;
    }
}
